<template>
  <div class="api-testing-tool">
    <div class="tool-header">
      <h1>API测试工具</h1>
      <p>在线API接口测试</p>
    </div>

    <div class="tool-container">
      <el-row :gutter="20">
        <!-- 测试主体 -->
        <el-col :span="16">
          <div class="testing-section">
            <!-- 请求配置 -->
            <div class="request-config">
              <h3>请求配置</h3>
              <div class="config-grid">
                <div class="config-item">
                  <label>请求方法：</label>
                  <el-select v-model="requestMethod" size="large">
                    <el-option label="GET" value="GET" />
                    <el-option label="POST" value="POST" />
                    <el-option label="PUT" value="PUT" />
                    <el-option label="DELETE" value="DELETE" />
                    <el-option label="PATCH" value="PATCH" />
                  </el-select>
                </div>
                
                <div class="config-item">
                  <label>URL：</label>
                  <el-input
                    v-model="requestUrl"
                    placeholder="请输入API地址"
                    size="large"
                  >
                    <template #prepend>
                      <el-icon><Link /></el-icon>
                    </template>
                  </el-input>
                </div>
              </div>
            </div>
            
            <!-- 请求头 -->
            <div class="request-headers">
              <h3>请求头</h3>
              <div class="headers-list">
                <div 
                  v-for="(header, index) in requestHeaders" 
                  :key="index"
                  class="header-item"
                >
                  <el-input
                    v-model="header.key"
                    placeholder="Header名称"
                    size="small"
                  />
                  <span class="separator">:</span>
                  <el-input
                    v-model="header.value"
                    placeholder="Header值"
                    size="small"
                  />
                  <el-button @click="removeHeader(index)" size="small" type="danger">
                    删除
                  </el-button>
                </div>
                <el-button @click="addHeader" size="small" type="primary">
                  <el-icon><Plus /></el-icon>
                  添加Header
                </el-button>
              </div>
            </div>
            
            <!-- 请求参数 -->
            <div class="request-params">
              <h3>请求参数</h3>
              <el-tabs v-model="paramsTab" type="card">
                <el-tab-pane label="Query参数" name="query">
                  <div class="params-list">
                    <div 
                      v-for="(param, index) in queryParams" 
                      :key="index"
                      class="param-item"
                    >
                      <el-input
                        v-model="param.key"
                        placeholder="参数名"
                        size="small"
                      />
                      <span class="separator">=</span>
                      <el-input
                        v-model="param.value"
                        placeholder="参数值"
                        size="small"
                      />
                      <el-button @click="removeQueryParam(index)" size="small" type="danger">
                        删除
                      </el-button>
                    </div>
                    <el-button @click="addQueryParam" size="small" type="primary">
                      <el-icon><Plus /></el-icon>
                      添加参数
                    </el-button>
                  </div>
                </el-tab-pane>
                
                <el-tab-pane label="Body参数" name="body">
                  <div class="body-config">
                    <div class="body-type">
                      <label>Body类型：</label>
                      <el-select v-model="bodyType" size="small">
                        <el-option label="JSON" value="json" />
                        <el-option label="Form Data" value="form" />
                        <el-option label="Raw Text" value="raw" />
                      </el-select>
                    </div>
                    
                    <div v-if="bodyType === 'json'" class="json-editor">
                      <el-input
                        v-model="bodyContent"
                        type="textarea"
                        :rows="8"
                        placeholder="请输入JSON数据"
                      />
                    </div>
                    
                    <div v-if="bodyType === 'form'" class="form-editor">
                      <div 
                        v-for="(param, index) in formParams" 
                        :key="index"
                        class="param-item"
                      >
                        <el-input
                          v-model="param.key"
                          placeholder="字段名"
                          size="small"
                        />
                        <span class="separator">=</span>
                        <el-input
                          v-model="param.value"
                          placeholder="字段值"
                          size="small"
                        />
                        <el-button @click="removeFormParam(index)" size="small" type="danger">
                          删除
                        </el-button>
                      </div>
                      <el-button @click="addFormParam" size="small" type="primary">
                        <el-icon><Plus /></el-icon>
                        添加字段
                      </el-button>
                    </div>
                    
                    <div v-if="bodyType === 'raw'" class="raw-editor">
                      <el-input
                        v-model="bodyContent"
                        type="textarea"
                        :rows="8"
                        placeholder="请输入原始文本"
                      />
                    </div>
                  </div>
                </el-tab-pane>
              </el-tabs>
            </div>
            
            <!-- 发送请求 -->
            <div class="send-request">
              <el-button @click="sendRequest" type="primary" size="large" :loading="isSending">
                <el-icon><Upload /></el-icon>
                发送请求
              </el-button>
              <el-button @click="clearRequest" size="large">
                清空
              </el-button>
            </div>
            
            <!-- 响应结果 -->
            <div class="response-result" v-if="responseResult">
              <h3>响应结果</h3>
              <div class="response-info">
                <div class="info-grid">
                  <div class="info-item">
                    <div class="info-label">状态码</div>
                    <div class="info-value" :class="getStatusClass(responseResult.status)">
                      {{ responseResult.status }}
                    </div>
                  </div>
                  <div class="info-item">
                    <div class="info-label">响应时间</div>
                    <div class="info-value">{{ responseResult.duration }}ms</div>
                  </div>
                  <div class="info-item">
                    <div class="info-label">响应大小</div>
                    <div class="info-value">{{ responseResult.size }}</div>
                  </div>
                  <div class="info-item">
                    <div class="info-label">Content-Type</div>
                    <div class="info-value">{{ responseResult.contentType }}</div>
                  </div>
                </div>
              </div>
              
              <div class="response-tabs">
                <el-tabs v-model="responseTab" type="card">
                  <el-tab-pane label="响应体" name="body">
                    <div class="response-body">
                      <el-input
                        v-model="responseResult.body"
                        type="textarea"
                        :rows="15"
                        readonly
                        class="response-textarea"
                      />
                    </div>
                  </el-tab-pane>
                  
                  <el-tab-pane label="响应头" name="headers">
                    <div class="response-headers">
                      <div 
                        v-for="(value, key) in responseResult.headers" 
                        :key="key"
                        class="header-row"
                      >
                        <div class="header-key">{{ key }}</div>
                        <div class="header-value">{{ value }}</div>
                      </div>
                    </div>
                  </el-tab-pane>
                  
                  <el-tab-pane label="请求信息" name="request">
                    <div class="request-info">
                      <div class="info-section">
                        <h4>请求URL</h4>
                        <div class="info-content">{{ responseResult.requestUrl }}</div>
                      </div>
                      <div class="info-section">
                        <h4>请求方法</h4>
                        <div class="info-content">{{ responseResult.requestMethod }}</div>
                      </div>
                      <div class="info-section">
                        <h4>请求头</h4>
                        <div class="info-content">
                          <pre>{{ JSON.stringify(responseResult.requestHeaders, null, 2) }}</pre>
                        </div>
                      </div>
                    </div>
                  </el-tab-pane>
                </el-tabs>
              </div>
            </div>
            
            <!-- 测试历史 -->
            <div class="test-history">
              <h3>测试历史</h3>
              <div class="history-list">
                <div 
                  v-for="(item, index) in testHistory" 
                  :key="index"
                  class="history-item"
                  @click="loadFromHistory(item)"
                >
                  <div class="history-method">{{ item.method }}</div>
                  <div class="history-url">{{ item.url }}</div>
                  <div class="history-info">
                    <span class="history-status" :class="getStatusClass(item.status)">{{ item.status }}</span>
                    <span class="history-time">{{ item.time }}</span>
                  </div>
                </div>
                <div v-if="testHistory.length === 0" class="empty-history">
                  暂无测试历史
                </div>
              </div>
            </div>
          </div>
        </el-col>

        <!-- 工具和说明 -->
        <el-col :span="8">
          <div class="tools-section">
            <div class="section-header">
              <h3>常用API</h3>
            </div>
            
            <div class="common-apis">
              <div 
                v-for="api in commonApis" 
                :key="api.url"
                class="api-item"
                @click="loadApi(api)"
              >
                <div class="api-method">{{ api.method }}</div>
                <div class="api-info">
                  <div class="api-name">{{ api.name }}</div>
                  <div class="api-url">{{ api.url }}</div>
                </div>
              </div>
            </div>
          </div>
          
          <div class="help-section">
            <el-card>
              <template #header>
                <div class="card-header">
                  <span>使用说明</span>
                </div>
              </template>
              
              <div class="help-content">
                <h4>支持的方法：</h4>
                <ul>
                  <li><strong>GET：</strong> 获取数据</li>
                  <li><strong>POST：</strong> 创建数据</li>
                  <li><strong>PUT：</strong> 更新数据</li>
                  <li><strong>DELETE：</strong> 删除数据</li>
                  <li><strong>PATCH：</strong> 部分更新</li>
                </ul>
                
                <h4>Body类型：</h4>
                <ul>
                  <li><strong>JSON：</strong> 结构化数据</li>
                  <li><strong>Form Data：</strong> 表单数据</li>
                  <li><strong>Raw Text：</strong> 原始文本</li>
                </ul>
                
                <h4>注意事项：</h4>
                <div class="warning">
                  <p>⚠️ 仅支持HTTPS和HTTP协议</p>
                  <p>⚠️ 某些API可能需要认证</p>
                  <p>⚠️ 注意跨域限制</p>
                </div>
              </div>
            </el-card>
          </div>
        </el-col>
      </el-row>
    </div>
  </div>
</template>

<script setup>
import { ref } from 'vue'
import { ElMessage } from 'element-plus'
import { Link, Plus, Upload } from '@element-plus/icons-vue'

const requestMethod = ref('GET')
const requestUrl = ref('')
const requestHeaders = ref([
  { key: 'Content-Type', value: 'application/json' }
])
const paramsTab = ref('query')
const queryParams = ref([])
const bodyType = ref('json')
const bodyContent = ref('')
const formParams = ref([])
const isSending = ref(false)
const responseResult = ref(null)
const responseTab = ref('body')
const testHistory = ref([])

const commonApis = [
  { method: 'GET', name: 'JSONPlaceholder Posts', url: 'https://jsonplaceholder.typicode.com/posts' },
  { method: 'GET', name: 'JSONPlaceholder Users', url: 'https://jsonplaceholder.typicode.com/users' },
  { method: 'POST', name: 'JSONPlaceholder Create Post', url: 'https://jsonplaceholder.typicode.com/posts' },
  { method: 'GET', name: 'HTTPBin Get', url: 'https://httpbin.org/get' },
  { method: 'POST', name: 'HTTPBin Post', url: 'https://httpbin.org/post' },
  { method: 'GET', name: 'HTTPBin Headers', url: 'https://httpbin.org/headers' }
]

const addHeader = () => {
  requestHeaders.value.push({ key: '', value: '' })
}

const removeHeader = (index) => {
  requestHeaders.value.splice(index, 1)
}

const addQueryParam = () => {
  queryParams.value.push({ key: '', value: '' })
}

const removeQueryParam = (index) => {
  queryParams.value.splice(index, 1)
}

const addFormParam = () => {
  formParams.value.push({ key: '', value: '' })
}

const removeFormParam = (index) => {
  formParams.value.splice(index, 1)
}

const sendRequest = async () => {
  if (!requestUrl.value.trim()) {
    ElMessage.warning('请输入API地址')
    return
  }
  
  isSending.value = true
  const startTime = Date.now()
  
  try {
    // 构建请求配置
    const config = {
      method: requestMethod.value,
      headers: {}
    }
    
    // 添加请求头
    requestHeaders.value.forEach(header => {
      if (header.key && header.value) {
        config.headers[header.key] = header.value
      }
    })
    
    // 构建URL
    let url = requestUrl.value
    if (queryParams.value.length > 0) {
      const params = new URLSearchParams()
      queryParams.value.forEach(param => {
        if (param.key && param.value) {
          params.append(param.key, param.value)
        }
      })
      url += '?' + params.toString()
    }
    
    // 添加请求体
    if (['POST', 'PUT', 'PATCH'].includes(requestMethod.value)) {
      if (bodyType.value === 'json' && bodyContent.value) {
        config.body = bodyContent.value
        config.headers['Content-Type'] = 'application/json'
      } else if (bodyType.value === 'form' && formParams.value.length > 0) {
        const formData = new FormData()
        formParams.value.forEach(param => {
          if (param.key && param.value) {
            formData.append(param.key, param.value)
          }
        })
        config.body = formData
      } else if (bodyType.value === 'raw' && bodyContent.value) {
        config.body = bodyContent.value
      }
    }
    
    // 模拟API调用（实际应用中需要处理CORS）
    await new Promise(resolve => setTimeout(resolve, 1000))
    
    // 模拟响应结果
    const duration = Date.now() - startTime
    const mockResponse = {
      status: Math.random() > 0.1 ? 200 : 404,
      duration: duration,
      size: '1.2 KB',
      contentType: 'application/json',
      body: JSON.stringify({
        message: 'This is a mock response',
        timestamp: new Date().toISOString(),
        method: requestMethod.value,
        url: url
      }, null, 2),
      headers: {
        'Content-Type': 'application/json',
        'Server': 'nginx/1.18.0',
        'Date': new Date().toUTCString()
      },
      requestUrl: url,
      requestMethod: requestMethod.value,
      requestHeaders: config.headers
    }
    
    responseResult.value = mockResponse
    
    // 添加到历史
    addToHistory()
    
    ElMessage.success('请求发送成功')
    
  } catch (error) {
    ElMessage.error('请求失败：' + error.message)
  } finally {
    isSending.value = false
  }
}

const clearRequest = () => {
  requestUrl.value = ''
  requestHeaders.value = [{ key: 'Content-Type', value: 'application/json' }]
  queryParams.value = []
  formParams.value = []
  bodyContent.value = ''
  responseResult.value = null
  ElMessage.info('请求已清空')
}

const getStatusClass = (status) => {
  if (status >= 200 && status < 300) return 'success'
  if (status >= 300 && status < 400) return 'warning'
  if (status >= 400 && status < 500) return 'danger'
  if (status >= 500) return 'danger'
  return 'info'
}

const addToHistory = () => {
  const historyItem = {
    method: requestMethod.value,
    url: requestUrl.value,
    status: responseResult.value.status,
    time: new Date().toLocaleString('zh-CN')
  }
  
  testHistory.value.unshift(historyItem)
  
  // 限制历史记录数量
  if (testHistory.value.length > 20) {
    testHistory.value = testHistory.value.slice(0, 20)
  }
}

const loadFromHistory = (item) => {
  requestMethod.value = item.method
  requestUrl.value = item.url
  ElMessage.success(`已加载：${item.method} ${item.url}`)
}

const loadApi = (api) => {
  requestMethod.value = api.method
  requestUrl.value = api.url
  ElMessage.success(`已加载：${api.name}`)
}
</script>

<style scoped>
.api-testing-tool {
  max-width: 1200px;
  margin: 0 auto;
  padding: 20px;
}

.tool-header {
  text-align: center;
  margin-bottom: 40px;
}

.tool-header h1 {
  font-size: 2.5rem;
  color: #333;
  margin-bottom: 10px;
}

.tool-header p {
  color: #666;
  font-size: 1.1rem;
}

.tool-container {
  margin-bottom: 40px;
}

.testing-section,
.tools-section {
  background: white;
  border-radius: 12px;
  padding: 24px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
  border: 1px solid #f0f0f0;
  height: 100%;
}

.request-config,
.request-headers,
.request-params,
.send-request,
.response-result,
.test-history {
  margin-bottom: 30px;
}

.request-config h3,
.request-headers h3,
.request-params h3,
.response-result h3,
.test-history h3 {
  color: #333;
  margin-bottom: 20px;
  font-size: 1.3rem;
}

.config-grid {
  display: grid;
  grid-template-columns: 1fr 3fr;
  gap: 15px;
}

.config-item {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.config-item label {
  font-weight: 500;
  color: #666;
}

.headers-list,
.params-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.header-item,
.param-item {
  display: flex;
  align-items: center;
  gap: 10px;
}

.separator {
  color: #666;
  font-weight: bold;
}

.body-config {
  display: flex;
  flex-direction: column;
  gap: 15px;
}

.body-type {
  display: flex;
  align-items: center;
  gap: 10px;
}

.body-type label {
  font-weight: 500;
  color: #666;
}

.json-editor,
.form-editor,
.raw-editor {
  margin-top: 10px;
}

.form-editor {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.send-request {
  display: flex;
  gap: 15px;
}

.response-info {
  background: #f8f9fa;
  border-radius: 8px;
  padding: 20px;
  margin-bottom: 20px;
  border: 1px solid #e9ecef;
}

.info-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 15px;
}

.info-item {
  text-align: center;
}

.info-label {
  font-size: 0.9rem;
  color: #666;
  margin-bottom: 5px;
}

.info-value {
  font-size: 1.2rem;
  font-weight: bold;
}

.info-value.success {
  color: #28a745;
}

.info-value.warning {
  color: #ffc107;
}

.info-value.danger {
  color: #dc3545;
}

.info-value.info {
  color: #17a2b8;
}

.response-tabs {
  background: #f8f9fa;
  border-radius: 8px;
  padding: 20px;
  border: 1px solid #e9ecef;
}

.response-body {
  margin-top: 15px;
}

.response-textarea {
  font-family: 'Courier New', monospace;
  font-size: 14px;
}

.response-headers {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-top: 15px;
}

.header-row {
  display: grid;
  grid-template-columns: 1fr 2fr;
  gap: 15px;
  padding: 10px;
  background: white;
  border-radius: 6px;
  border: 1px solid #e9ecef;
}

.header-key {
  font-weight: bold;
  color: #333;
}

.header-value {
  color: #666;
  word-break: break-all;
}

.request-info {
  margin-top: 15px;
}

.info-section {
  margin-bottom: 20px;
}

.info-section h4 {
  color: #333;
  margin-bottom: 10px;
  font-size: 1.1rem;
}

.info-content {
  background: white;
  padding: 15px;
  border-radius: 6px;
  border: 1px solid #e9ecef;
  font-family: 'Courier New', monospace;
  font-size: 14px;
  color: #666;
}

.history-list {
  max-height: 300px;
  overflow-y: auto;
}

.history-item {
  background: #f8f9fa;
  border-radius: 8px;
  padding: 15px;
  margin-bottom: 10px;
  cursor: pointer;
  transition: all 0.2s ease;
  border: 1px solid #e9ecef;
}

.history-item:hover {
  background: #e9ecef;
  transform: translateY(-1px);
}

.history-method {
  font-size: 0.9rem;
  font-weight: bold;
  color: #667eea;
  margin-bottom: 5px;
}

.history-url {
  font-size: 1rem;
  color: #333;
  margin-bottom: 8px;
  word-break: break-all;
}

.history-info {
  display: flex;
  gap: 15px;
  font-size: 0.9rem;
}

.history-status {
  padding: 2px 8px;
  border-radius: 4px;
  font-size: 0.8rem;
  font-weight: bold;
}

.history-status.success {
  background: #d4edda;
  color: #28a745;
}

.history-status.warning {
  background: #fff3cd;
  color: #ffc107;
}

.history-status.danger {
  background: #f8d7da;
  color: #dc3545;
}

.history-status.info {
  background: #d1ecf1;
  color: #17a2b8;
}

.history-time {
  color: #999;
}

.empty-history {
  text-align: center;
  color: #999;
  padding: 40px 0;
  font-style: italic;
}

.section-header {
  margin-bottom: 20px;
}

.section-header h3 {
  color: #333;
  margin: 0;
  font-size: 1.3rem;
}

.common-apis {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.api-item {
  display: flex;
  align-items: center;
  gap: 15px;
  background: #f8f9fa;
  border-radius: 8px;
  padding: 15px;
  cursor: pointer;
  transition: all 0.2s ease;
  border: 1px solid #e9ecef;
}

.api-item:hover {
  background: #e9ecef;
  transform: translateY(-2px);
}

.api-method {
  font-size: 0.8rem;
  font-weight: bold;
  padding: 4px 8px;
  border-radius: 4px;
  color: white;
  min-width: 50px;
  text-align: center;
}

.api-method {
  background: #667eea;
}

.api-name {
  font-size: 1rem;
  font-weight: bold;
  color: #333;
  margin-bottom: 2px;
}

.api-url {
  font-size: 0.9rem;
  color: #666;
  word-break: break-all;
}

.help-section {
  margin-top: 20px;
}

.card-header {
  font-weight: bold;
  color: #333;
}

.help-content h4 {
  color: #333;
  margin: 20px 0 10px 0;
  font-size: 1.1rem;
}

.help-content ul {
  color: #666;
  padding-left: 20px;
  margin-bottom: 15px;
}

.help-content li {
  margin-bottom: 5px;
}

.warning {
  background: #fff3cd;
  padding: 15px;
  border-radius: 8px;
  border-left: 4px solid #ffc107;
  margin: 15px 0;
}

.warning p {
  margin: 5px 0;
  color: #856404;
}

@media (max-width: 768px) {
  .tool-header h1 {
    font-size: 2rem;
  }
  
  .config-grid {
    grid-template-columns: 1fr;
  }
  
  .header-item,
  .param-item {
    flex-direction: column;
    align-items: stretch;
  }
  
  .separator {
    display: none;
  }
  
  .info-grid {
    grid-template-columns: repeat(2, 1fr);
  }
  
  .header-row {
    grid-template-columns: 1fr;
  }
  
  .history-info {
    flex-direction: column;
    gap: 5px;
  }
}
</style>
